package jmine.tec.web.servlet.listener;

import javax.security.auth.Subject;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import bancosys.tec.security.impl.UsersLoggedCounter;
import bancosys.tec.security.impl.web.WebSecurityManager;

/**
 * Listener que cuida de incrementar/decrementar contador de usuarios logados quando um usuario fizer login/logoff no sistema.
 * 
 * @author Marcio Ribeiro (mmr)
 * @created Dec 9, 2011
 */
public class UserLoginServletListener implements HttpSessionAttributeListener, HttpSessionListener {

    private static final String USERS_LOGGED_COUNTER = "usersLoggedCounter";

    /**
     * Chamado quando um atributo for adicionado a sessao. Se for um usuario significa que usuario fez login, deve incrementar contador.
     * 
     * @param se binding event.
     */
    public void attributeAdded(HttpSessionBindingEvent se) {
        if (se.getValue() instanceof Subject) {
            this.getCounter(se).increment();
        }
    }

    /**
     * @param se session binding event.
     * @return spring bean com contador de usuarios logados.
     */
    private UsersLoggedCounter getCounter(HttpSessionEvent se) {
        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(se.getSession().getServletContext());
        return (UsersLoggedCounter) ctx.getBean(USERS_LOGGED_COUNTER);
    }

    /**
     * Sessao foi destruida, verifica se havia um usuario logado, se sim, decrementa contador.
     * 
     * @param se evento.
     */
    public void sessionDestroyed(HttpSessionEvent se) {
        Object user = se.getSession().getAttribute(WebSecurityManager.SESSION_KEY);
        if (user != null) {
            this.getCounter(se).decrement();
        }
    }

    /**
     * {@inheritDoc}
     */
    public void attributeRemoved(HttpSessionBindingEvent se) {
        // do nothing
    }

    /**
     * {@inheritDoc}
     */
    public void attributeReplaced(HttpSessionBindingEvent se) {
        // do nothing
    }

    /**
     * {@inheritDoc}
     */
    public void sessionCreated(HttpSessionEvent se) {
        // do nothing
    }
}
